﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Reflection;
using System.Resources;
using System.Text;
using System.Threading;

namespace DotNETX.Utility.Resources
{
    public class ResourceLoader 
    {
        private readonly ResourceManager _resourceManager;
        private System.Globalization.CultureInfo _resourceCulture;

        public ResourceLoader(Assembly resourceAssembly)
            : this(resourceAssembly, null)
        {
        }

        public ResourceLoader(Assembly resourceAssembly, string resourceName)
        {

            // assembly that resources are loader from is determined by the assembly of the assembly marker type
            string assemblyName = resourceAssembly.GetName().Name;

            List<string> assemblyResourceNames = new List<string>(resourceAssembly.GetManifestResourceNames());

            if (assemblyResourceNames == null || assemblyResourceNames.Count == 0)
                throw new Exception(string.Format("There is no embedded resource file in assembly {0}.", assemblyName));


            if (!assemblyResourceNames.Contains(resourceName))
            {
                resourceName = assemblyResourceNames[0];
                resourceName = resourceName.Remove(resourceName.Length - ".resource".Length - 1);
                _resourceManager = new ResourceManager(resourceName, resourceAssembly);
            }
            else
            {
                _resourceManager = new ResourceManager(resourceName, resourceAssembly);
            }
        }

        public ResourceManager ResourceManager
        {
            get { return _resourceManager; }
        }

        internal System.Globalization.CultureInfo Culture
        {
            get
            {
                if (_resourceCulture != null)
                    return _resourceCulture;
                else
                    return CultureInfo.CurrentUICulture;
            }
            set
            {
                _resourceCulture = value;
            }
        }

        public string GetString(string name)
        {
            string resourceValue = _resourceManager.GetString(name, Culture);

            if (resourceValue == null)
                throw new Exception(string.Format("Resource '{0}' not found in {1}.", name, _resourceManager.BaseName));

            return resourceValue;
        }

        public string GetString(string name, params object[] values)
        {
            string resourceValue = GetString(name, Culture);

            return string.Format(Culture, resourceValue, values);
        }

        public object GetObject(string name)
        {
            object resourceValue = _resourceManager.GetObject(name, Culture);

            if (resourceValue == null)
                throw new Exception(string.Format("Resource '{0}' not found in {1}.", name, _resourceManager.BaseName));

            return resourceValue;
        }

        public T GetObject<T>(string name)
        {
            object value = GetObject(name);

            if (!(value is T))
                throw new Exception(string.Format("Resource '{0}' is of type {1}, not {2}.", name, value.GetType(), typeof(T)));

            return (T)value;
        }
    }
}
